package ws

import "encoding/json"

const GroupKey = "group"
const SubscribeKey = "subscribe"
const UnSubscribeKey = "unsubscribe"

//FeatureSubscribeMgr ws订阅功能，负责解析和管理订阅Group
type FeatureSubscribeMgr struct {
	groups map[string]ISubscribeGroup
}

func NewFeatureSubscribeMgr(groups ...ISubscribeGroup) *FeatureSubscribeMgr {
	gm := make(map[string]ISubscribeGroup, len(groups))
	for _, v := range groups {
		gm[v.Name()] = v
	}

	return &FeatureSubscribeMgr{
		groups: gm,
	}
}

//Parse 解析订阅数据，返回参数：
//    group,对应group
//    bool，true：加入订阅，false：退出订阅
//   如果对应数据格式是group的则返回的bool不准确，由上层自己判断
//   	支持的数据格式1： {"action":"subscribe","group":"Trade"}
//          上面这个数据格式适用于配合 FeatureActionsMgr 使用
//   	支持的数据格式2： {"subscribe":"Trade"}
//   	支持的数据格式3： {"unsubscribe":"Trade"}
func (sub *FeatureSubscribeMgr) Parse(data []byte) (ISubscribeGroup, bool) {
	m := make(map[string]string, 10)
	//m["1"] = "1"

	if err := json.Unmarshal(data, &m); err != nil {
		logger.Error("parse err %s", err)
		return nil, false
	}

	//logger.Info("%s,%v", string(data), m)
	if name, exist := m[GroupKey]; exist {
		return sub.groups[name], true
	}
	if name, exist := m[SubscribeKey]; exist {
		//返回对应group，group=nil是不加入，!=nil则是真正加入
		return sub.groups[name], true
	}
	if name, exist := m[UnSubscribeKey]; exist {
		//返回对应group，group=nil则也是不加入的
		return sub.groups[name], false
	}

	return nil, false
}

//ParseJoinGroup 解析并自动加入group,返回:
//		group, 对应group名称, group为nil表示group不存在
//		join, true：订阅加入，false：订阅退出
func (sub *FeatureSubscribeMgr) ParseJoinGroup(client *Client, data []byte) (ISubscribeGroup, bool) {
	group, join := sub.Parse(data)
	if group == nil {
		return nil, false
	}
	if join {
		sub.JoinGroup(client, group.Name())
	} else {
		sub.QuitGroup(client, group.Name())
	}
	return group, join
}

//QuitAllGroup 退出所有group
func (sub *FeatureSubscribeMgr) QuitAllGroup(client *Client) {
	for _, c := range sub.groups {
		c.DeleteClient(client)
	}
}

//JoinGroup 加入指定group
func (sub *FeatureSubscribeMgr) JoinGroup(client *Client, name string) bool {
	if g, exist := sub.groups[name]; exist {
		logger.Info("subscribe group [%s]", g.Name())
		g.AddClient(client)
		return true
	}
	return false
}

//QuitGroup 退出指定group
func (sub *FeatureSubscribeMgr) QuitGroup(client *Client, name string) bool {
	if g, exist := sub.groups[name]; exist {
		logger.Info("unsubscribe group [%s]", g.Name())
		g.DeleteClient(client)
		return true
	}
	return false
}

//Groups 所有groups
func (sub *FeatureSubscribeMgr) Groups() map[string]ISubscribeGroup {
	return sub.groups
}

//Group 指定group
func (sub *FeatureSubscribeMgr) Group(name string) ISubscribeGroup {
	return sub.groups[name]
}

//Subscribe 订阅方法，用于只处理订阅数据
func (sub *FeatureSubscribeMgr) Subscribe(client *Client, data []byte) ISubscribeGroup {
	g, _ := sub.Parse(data)
	if g != nil {
		sub.JoinGroup(client, g.Name())
	}
	return g
}

//UnSubscribe 取消订阅方法，用于只处理取消订阅数据
func (sub *FeatureSubscribeMgr) UnSubscribe(client *Client, data []byte) ISubscribeGroup {
	g, _ := sub.Parse(data)
	if g != nil {
		sub.QuitGroup(client, g.Name())
	}
	return g
}

func (sub *FeatureSubscribeMgr) SubscribeAction(client *Client, data []byte) {
	g := sub.Subscribe(client, data)
	logger.Debug("subscribe group %t", g == nil)
}

func (sub *FeatureSubscribeMgr) UnSubscribeAction(client *Client, data []byte) {
	g := sub.UnSubscribe(client, data)
	logger.Debug("unsubscribe group %t", g == nil)
}
